// SPDX-FileCopyrightText: Copyright 2025-2025 深圳市同心圆网络有限公司
// SPDX-License-Identifier: Apache-2.0

package roadmap_data_state_api_serv

import (
	"context"
	"time"

	"gitcode.com/lvupclub/lvup-api/dao"
	"gitcode.com/lvupclub/lvup-api/dao/roadmap_dao"
	"gitcode.com/lvupclub/proto-gen-go.git/src/roadmap_data_state_api"
	"gitcode.com/lvupclub/proto-gen-go.git/src/roadmap_data_type_api"
	"github.com/google/uuid"
	"google.golang.org/protobuf/proto"
	"google.golang.org/protobuf/types/known/anypb"
)

type RoadmapDataStateApiImpl struct {
	roadmap_data_state_api.UnimplementedRoadmapDataStateApiServer
}

func (apiImpl *RoadmapDataStateApiImpl) Add(ctx context.Context, req *roadmap_data_state_api.AddRequest) (*roadmap_data_state_api.AddResponse, error) {
	sessItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &roadmap_data_state_api.AddResponse{
			Code:   roadmap_data_state_api.AddResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	roadmapItem, err := roadmap_dao.RoadmapInfoDao.Get(ctx, req.RoadmapId)
	if err != nil {
		return &roadmap_data_state_api.AddResponse{
			Code:   roadmap_data_state_api.AddResponse_CODE_NO_ROADMAP,
			ErrMsg: "成长路线图不存在",
		}, nil
	}
	if roadmapItem.OwnerUserId != sessItem.UserId {
		exist, err := roadmap_dao.RoadmapMemberDao.Exist(ctx, req.RoadmapId, sessItem.UserId)
		if err != nil {
			return nil, err
		}
		if !exist {
			return &roadmap_data_state_api.AddResponse{
				Code:   roadmap_data_state_api.AddResponse_CODE_NO_PERMISSION,
				ErrMsg: "没有权限",
			}, nil
		}
	}
	//检查节点是否存在
	exist, err := roadmap_dao.NodeInfoDao.Exist(ctx, req.RoadmapId, req.NodeId)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &roadmap_data_state_api.AddResponse{
			Code:   roadmap_data_state_api.AddResponse_CODE_NO_NODE,
			ErrMsg: "成长路线图节点不存在",
		}, nil
	}

	stateData, err := proto.Marshal(req.State)
	if err != nil {
		return nil, err
	}

	nowTime := time.Now().UnixMilli()
	stateId := uuid.NewString()

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx context.Context) (interface{}, error) {
		err = roadmap_dao.NodeStateInfoDao.Insert(sessCtx, &roadmap_dao.NodeStateInfoDbItem{
			StateId:      stateId,
			RoadmapId:    req.RoadmapId,
			MemberUserId: sessItem.UserId,
			NodeId:       req.NodeId,
			StateData:    stateData,
			TimeStamp:    nowTime,
		})
		if err != nil {
			return nil, err
		}
		return &roadmap_data_state_api.AddResponse{
			Code:    roadmap_data_state_api.AddResponse_CODE_OK,
			StateId: stateId,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	return ret.(*roadmap_data_state_api.AddResponse), nil
}

func (apiImpl *RoadmapDataStateApiImpl) Remove(ctx context.Context, req *roadmap_data_state_api.RemoveRequest) (*roadmap_data_state_api.RemoveResponse, error) {
	sessItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &roadmap_data_state_api.RemoveResponse{
			Code:   roadmap_data_state_api.RemoveResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	roadmapItem, err := roadmap_dao.RoadmapInfoDao.Get(ctx, req.RoadmapId)
	if err != nil {
		return &roadmap_data_state_api.RemoveResponse{
			Code:   roadmap_data_state_api.RemoveResponse_CODE_NO_ROADMAP,
			ErrMsg: "成长路线图不存在",
		}, nil
	}
	if roadmapItem.OwnerUserId != sessItem.UserId {
		exist, err := roadmap_dao.RoadmapMemberDao.Exist(ctx, req.RoadmapId, sessItem.UserId)
		if err != nil {
			return nil, err
		}
		if !exist {
			return &roadmap_data_state_api.RemoveResponse{
				Code:   roadmap_data_state_api.RemoveResponse_CODE_NO_PERMISSION,
				ErrMsg: "没有权限",
			}, nil
		}
	}
	//检查节点是否存在
	exist, err := roadmap_dao.NodeInfoDao.Exist(ctx, req.RoadmapId, req.NodeId)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &roadmap_data_state_api.RemoveResponse{
			Code:   roadmap_data_state_api.RemoveResponse_CODE_NO_NODE,
			ErrMsg: "成长路线图节点不存在",
		}, nil
	}
	//检查状态是否存在
	exist, err = roadmap_dao.NodeStateInfoDao.Exist(ctx, req.StateId, req.RoadmapId, req.NodeId, sessItem.UserId)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &roadmap_data_state_api.RemoveResponse{
			Code: roadmap_data_state_api.RemoveResponse_CODE_OK,
		}, nil
	}

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx context.Context) (interface{}, error) {
		err = roadmap_dao.NodeStateInfoDao.Remove(sessCtx, req.StateId, req.RoadmapId, req.NodeId, sessItem.UserId)
		if err != nil {
			return nil, err
		}
		return &roadmap_data_state_api.RemoveResponse{
			Code: roadmap_data_state_api.RemoveResponse_CODE_OK,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	return ret.(*roadmap_data_state_api.RemoveResponse), nil
}

func (apiImpl *RoadmapDataStateApiImpl) List(ctx context.Context, req *roadmap_data_state_api.ListRequest) (*roadmap_data_state_api.ListResponse, error) {
	emptyList := []*roadmap_data_state_api.NodeStateInfo{}

	sessItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &roadmap_data_state_api.ListResponse{
			Code:      roadmap_data_state_api.ListResponse_CODE_WRONG_SESSION,
			ErrMsg:    "会话不存在",
			StateList: emptyList,
		}, nil
	}
	roadmapItem, err := roadmap_dao.RoadmapInfoDao.Get(ctx, req.RoadmapId)
	if err != nil {
		return &roadmap_data_state_api.ListResponse{
			Code:      roadmap_data_state_api.ListResponse_CODE_NO_ROADMAP,
			ErrMsg:    "成长路线图不存在",
			StateList: emptyList,
		}, nil
	}
	if roadmapItem.OwnerUserId == sessItem.UserId { //用户是路线图owner
		if sessItem.UserId != req.TargetMemberUserId {
			exist, err := roadmap_dao.RoadmapMemberDao.Exist(ctx, req.RoadmapId, req.TargetMemberUserId)
			if err != nil {
				return nil, err
			}
			if !exist {
				return &roadmap_data_state_api.ListResponse{
					Code:      roadmap_data_state_api.ListResponse_CODE_NO_PERMISSION,
					ErrMsg:    "没有权限",
					StateList: emptyList,
				}, nil
			}
		}
	} else { //路线图成员
		if sessItem.UserId != req.TargetMemberUserId {
			return &roadmap_data_state_api.ListResponse{
				Code:      roadmap_data_state_api.ListResponse_CODE_NO_PERMISSION,
				ErrMsg:    "没有权限",
				StateList: emptyList,
			}, nil
		}
		exist, err := roadmap_dao.RoadmapMemberDao.Exist(ctx, req.RoadmapId, req.TargetMemberUserId)
		if err != nil {
			return nil, err
		}
		if !exist {
			return &roadmap_data_state_api.ListResponse{
				Code:      roadmap_data_state_api.ListResponse_CODE_NO_PERMISSION,
				ErrMsg:    "没有权限",
				StateList: emptyList,
			}, nil
		}
	}

	stateItemList, err := roadmap_dao.NodeStateInfoDao.List(ctx, req.RoadmapId, req.TargetMemberUserId)
	if err != nil {
		return nil, err
	}
	stateList := []*roadmap_data_state_api.NodeStateInfo{}
	for _, stateItem := range stateItemList {
		state, err := stateItem.ToNodeStateInfo()
		if err != nil {
			continue
		}
		stateList = append(stateList, state)
	}
	return &roadmap_data_state_api.ListResponse{
		Code:      roadmap_data_state_api.ListResponse_CODE_OK,
		StateList: stateList,
	}, nil
}

func (apiImpl *RoadmapDataStateApiImpl) Get(ctx context.Context, req *roadmap_data_state_api.GetRequest) (*roadmap_data_state_api.GetResponse, error) {
	unknownState, _ := anypb.New(&roadmap_data_type_api.UnknownState{})
	emptyInfo := &roadmap_data_state_api.NodeStateInfo{
		State: unknownState,
	}

	sessItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &roadmap_data_state_api.GetResponse{
			Code:   roadmap_data_state_api.GetResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
			State:  emptyInfo,
		}, nil
	}
	roadmapItem, err := roadmap_dao.RoadmapInfoDao.Get(ctx, req.RoadmapId)
	if err != nil {
		return &roadmap_data_state_api.GetResponse{
			Code:   roadmap_data_state_api.GetResponse_CODE_NO_ROADMAP,
			ErrMsg: "成长路线图不存在",
			State:  emptyInfo,
		}, nil
	}
	if roadmapItem.OwnerUserId != sessItem.UserId { //用户是路线图owner
		exist, err := roadmap_dao.RoadmapMemberDao.Exist(ctx, req.RoadmapId, sessItem.UserId)
		if err != nil {
			return nil, err
		}
		if !exist {
			return &roadmap_data_state_api.GetResponse{
				Code:   roadmap_data_state_api.GetResponse_CODE_NO_PERMISSION,
				ErrMsg: "没有权限",
				State:  emptyInfo,
			}, nil
		}
	}

	stateItem, err := roadmap_dao.NodeStateInfoDao.Get(ctx, req.StateId, req.RoadmapId, req.NodeId, sessItem.UserId)
	if err != nil {
		return &roadmap_data_state_api.GetResponse{
			Code:   roadmap_data_state_api.GetResponse_CODE_NO_STATE,
			ErrMsg: "成长状态不存在",
			State:  emptyInfo,
		}, nil
	}
	state, err := stateItem.ToNodeStateInfo()
	if err != nil {
		return nil, err
	}
	return &roadmap_data_state_api.GetResponse{
		Code:  roadmap_data_state_api.GetResponse_CODE_OK,
		State: state,
	}, nil
}
